#pragma once


#include <IXHeader.h>
#include <IXTimer.h>
#include "XFrameImpl.h"
#include <IXImageDraw.h>

#include <vector>

enum HitTestCode
{
    HHC_None = 0,
    HHC_SplitMargin,
    HHC_Center,
};

template <class I>
class CXHeaderImpl : public CXFrameImpl<I>, public IXTimer
{
    typedef CXFrameImpl<I> superclass;

    BEGIN_DEF_SKIN_CLASS(CXHeader, superclass, gs_strGuidXSkin)
        IMP_BASIC_INTF(IXHeader,    0)
    END_DEF_SKIN_CLASS();

    IMPL_CONTROL_OBJ(CXHeaderImpl, superclass, _T("Header"));

public:
    CXHeaderImpl();
    virtual ~CXHeaderImpl();

public:
    // IXHeader
    virtual int  STDMETHODCALLTYPE   InsertItem(IN int nIndex, IN LPCTSTR szText);
    virtual int  STDMETHODCALLTYPE   InsertItem(IN int nIndex, IN LPCTSTR szText, IN DWORD dwTextEnvFlags, IN int nWidth);

    virtual int  STDMETHODCALLTYPE   GetItemCount();

    virtual int  STDMETHODCALLTYPE   GetItemWidth(IN int nIndex);
    virtual void STDMETHODCALLTYPE   SetItemWidth(IN int nIndex, IN int nWidth);
    virtual int  STDMETHODCALLTYPE   GetTotalWidth();

    virtual DWORD STDMETHODCALLTYPE  GetItemData(IN int nIndex);
    virtual void STDMETHODCALLTYPE   SetItemData(IN int nIndex, IN DWORD dwData);

    virtual void STDMETHODCALLTYPE   RemoveItem(IN int nIndex);
    virtual void STDMETHODCALLTYPE   RemoveAllItems();

    virtual void STDMETHODCALLTYPE   SetItemFlags(IN int nIndex, IN DWORD dwFlags);
    virtual DWORD STDMETHODCALLTYPE  GetItemFlags(IN int nIndex);

    virtual int  STDMETHODCALLTYPE   GetSortIndex();
    virtual BOOL STDMETHODCALLTYPE   GetSortAsc();

public:
    // IXFrame
    virtual void STDMETHODCALLTYPE   GetAutoSize(OUT LPSIZE pAutoSize);
    virtual void STDMETHODCALLTYPE   Draw(XCANVAS xCanvas, const RECT& rcDraw);

    virtual HCURSOR STDMETHODCALLTYPE GetCursor(IN POINT* pt);

    virtual BOOL STDMETHODCALLTYPE   OnMouseDown(POINT* pt);
    virtual BOOL STDMETHODCALLTYPE   OnMouseUp(POINT* pt);

    virtual BOOL STDMETHODCALLTYPE   OnMouseMove(IN POINT* pt);
    virtual BOOL STDMETHODCALLTYPE   OnMouseLeave(POINT* pt);

public:
    // IXBaseObj
    virtual void STDMETHODCALLTYPE   OnFinalRelease();

public:
    // IXTimer
    virtual void STDMETHODCALLTYPE   OnTimer(UINT_PTR uTimerId, void* pData);

protected:

    // CXControlImpl
    virtual void    AutoSizeImpl(BOOL bForce);
    virtual BOOL    OnClicked(const POINT* pt);
    virtual HRESULT OnSkinLangChanged();

    // CXHeaderImpl
    int HitTest(IN const POINT& pt, OUT HitTestCode& code);

    void CancelDrag();

protected:
    typedef struct 
    {
        XString strText;
        XString strTextResId;
        DWORD   dwData;
        DWORD   dwDrawFlags;
        int     nMinWidth;
        int     nWidth;
        DWORD   dwFlags;
    } ItemInfo;
    typedef std::vector<ItemInfo> ItemInfoContainter;
    ItemInfoContainter m_ItemInfos;

    BOOL        m_bSizeChanging;
    int         m_nDragIndex;
    int         m_nOrgX;

    IXImageDraw*    m_pArrow;
    UINT_PTR    m_uWidthChangedTimerId;

    int         m_nSortIndex;
    int         m_nClickedIndex;
    BOOL        m_bSortAsc;

    HCURSOR     m_hSplitCursor;
};


class CXHeader : public CXHeaderImpl<IXHeader>
{
};
